package com.nercel.dsj.gksales.service.impl;

import com.alipay.api.internal.util.StringUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.nercel.dsj.gksales.dao.mapper.UserMapper;
import com.nercel.dsj.gksales.exception.ResponseCode;
import com.nercel.dsj.gksales.exception.RestApiException;
import com.nercel.dsj.gksales.model.ListResult;
import com.nercel.dsj.gksales.model.QueryParams;
import com.nercel.dsj.gksales.model.RowData;
import com.nercel.dsj.gksales.model.RowDataList;
import com.nercel.dsj.gksales.model.dto.ImportResultDTO;
import com.nercel.dsj.gksales.model.entity.Configuration;
import com.nercel.dsj.gksales.model.entity.Role;
import com.nercel.dsj.gksales.model.entity.User;
import com.nercel.dsj.gksales.service.ConfigurationService;
import com.nercel.dsj.gksales.service.RoleService;
import com.nercel.dsj.gksales.service.SmsService;
import com.nercel.dsj.gksales.service.UserService;
import com.nercel.dsj.gksales.shiro.util.ExcelUtil;
import com.nercel.dsj.gksales.util.Md5Util;
import com.nercel.dsj.gksales.util.StringUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.*;

/**
 * @author sunlin
 * @date 2018-11-16
 */
@Service
@Transactional
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;

    private final RoleService roleService;

    private final SmsService smsService;

	private final ConfigurationService configurationService;

    @Override
    public void save(User user) {
        user.setCreateTime(new Date());
        userMapper.insertSelective(user);
    }

    @Override
    public void update(User user) {
        userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public User findById(Integer id) {
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<User> listAll() {
        return null;
    }

    @Override
    public void delete(Integer id) {
        userMapper.deleteByPrimaryKey(id);
    }

    @Override
    public ListResult<User> listWithPaging(QueryParams queryParams) {
        Page<User> page = PageHelper.startPage(queryParams.getPageNumber(), queryParams.getPageSize());
        userMapper.query(queryParams);
        return new ListResult<>(page);
    }

    @Override
    public void updateRoles(Integer userId, List<Integer> roleIds) {
        userMapper.updateRoles(userId, roleIds);
    }

    @Override
    public void addRoles(Integer userId, List<Integer> roleIds) {
        List<Role> roleList = roleService.selectByUserIdWithPermissions(userId);
        List<Integer> roles = new ArrayList<>();
        List<Role> userRoles = roleList == null ? new ArrayList<>() : roleList;
        userRoles.forEach(role -> {
            if(!roleIds.contains(role.getId())) {
                roles.add(role.getId());
            }
        });
        roles.addAll(roleIds);
        updateRoles(userId, roles);
    }

    @Override
    public void removeRoles(Integer userId, List<Integer> roleIds) {
        List<Role> roleList = roleService.selectByUserIdWithPermissions(userId);
        List<Integer> roles = new ArrayList<>();
        List<Role> userRoles = roleList == null ? new ArrayList<>() : roleList;
        userRoles.forEach(role -> {
            if(!roleIds.contains(role.getId())){
                roles.add(role.getId());
            }
        });
        updateRoles(userId, roles);
    }

    @Override
    public User findByPhone(String phone) {
        if(phone == null || phone.equals("")){
            return null;
        }
        QueryParams queryParams = new QueryParams();
        queryParams.put("phone", phone);
        List<User> list = userMapper.query(queryParams);
        return list.size() == 0 ? null : list.get(0);
    }

    @Transactional
    public ImportResultDTO importFromExcel(File file, Integer userId, String level) {
        ImportResultDTO resultDTO = new ImportResultDTO();
        User creater = findById(userId);
        RowDataList data = ExcelUtil.parseExcelFile(file);
        Map<String, String> smsData = new HashMap<>();
        int startIndex = 1;
        for(int i = startIndex; i < data.size(); i++) {
            RowData row = data.get(i);
            User user = new User();
            user.setPhone(row.get("C"));
            user.setBankAccount(row.get("G"));
            user.setCounty(row.get("D"));
            user.setName(row.get("A"));
            user.setUserNumber(row.get("B"));
            user.setChannelName(row.get("E"));
            user.setChannelNumber(row.get("F"));
            user.setBankInfo(row.get("H"));
            user.setRemark(row.get("I"));
            user.setCreateTime(new Date());
            user.setProvinceId(creater.getProvinceId());
            user.setCityId(creater.getCityId());
            user.setProvince(creater.getProvince());
            user.setCity(creater.getCity());
            user.setLevel(3);
            user.setDeleted(false);
            user.setActivated(true);
            String salt = StringUtil.randomUUID().substring(0, 6);
            String pwd = StringUtil.randomUUID().substring(0, 6);
            //发短信
            String password = Md5Util.getMD5String(salt + pwd);
            user.setPassword(password);
            user.setSalt(salt);
            if(!user.getPhone().matches("\\d{11}")){
                resultDTO.failedIncrement();
                resultDTO.addMessage(user.getPhone() +"," + user.getName() + ",手机号错误");
            }if (findByPhone(user.getPhone()) == null) {
                save(user);
                resultDTO.insertIncrement();
                smsData.put(user.getPhone(), pwd);
            } else {
                resultDTO.ignoreIncrement();
                resultDTO.addMessage(user.getPhone() + "," + user.getName() + ",跳过");
            }
        }
        if(resultDTO.getInsert() >0){
            smsService.sendNewUserPwd(smsData);
        }
        return resultDTO;
    }

}
